package org.littlesun.management.address;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import lombok.AllArgsConstructor;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.ToString;

@AllArgsConstructor
@ToString(of={"name"})
@EqualsAndHashCode(of={"name"})
public class City implements Area {

	@Getter private String name;
	@Getter private boolean zoneAsBeginOfAddress;
	@Getter private List<String> aliases = new ArrayList<String>();
	@Getter private List<Zone> zones = new ArrayList<Zone>();
	@Getter private List<Road> roads = new ArrayList<Road>();
	
	public City(String name) {
		this(name, true);
	}
	
	public City(String name, boolean zoneAsBeginOfAddress) {
		this(name, new String[] {}, zoneAsBeginOfAddress);
	}
	
	public City(String name, String[] aliases, boolean zoneAsBeginOfAddress) {
		this(name, zoneAsBeginOfAddress, new ArrayList<String>(Arrays.asList(aliases)), new ArrayList<Zone>(), new ArrayList<Road>());
	}
	
	public Zone addZone(String zoneName) {
		return addZone(zoneName, new String[] {});
	}
	
	public Zone addZone(String zoneName, String[] roadNames) {
		Zone zone = findZone(zoneName);
		if (zone != null) {
			throw new RuntimeException("zone already exist!" + zoneName);
		}
		zone = new Zone(this, zoneName);
		for(String roadName : roadNames) {
			if (roadName == null) {
				throw new NullPointerException("roadName");
			}
			Road road = findRoad(roadName);
			if (road == null) {
				road = new Road(this, roadName);
			}
			this.addRoad(road);
			zone.addRoad(road);
		}
		this.zones.add(zone);
		return zone;
	}

	public void addRoad(Road road) {
		if (!this.roads.contains(road)) {
			this.roads.add(road);
		}
	}

	public Zone findZone(String name) {
		for(Zone zone : this.zones) {
			if (zone.getName().equals(name)) {
				return zone;
			}
		}
		return null;
	}
	
	public Road findRoad(String name) {
		for(Road road : this.roads) {
			if (road.getName().equals(name)) {
				return road;
			}
		}
		return null;
	}

	public void addAliases(String... aliases) {
		this.aliases.addAll(Arrays.asList(aliases));
	}

}
